package fr.inserm.u915.tabixserver;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import fr.inserm.u915.tabixserver.expr.ExprNode;

public class Table extends Named
	{
	private List<Column> columns=new ArrayList<Column>();
	private Column chromColumn=null;
	private Column startColumn=null;
	private Column endColumn=null;
	private Column nameColumn=null;
	private Column strandColumn=null;
	private FirstBase firstBase=FirstBase.ZERO;
	/* chromosome name normalizer. Default is UCSC */
	private ChromNameNormalizer chromosomeNaming=new UCSCNameNormalizer();
	private String pattern="[\t]";
	private Map<String,Column> id2column=new HashMap<String, Column>();
	private ExprNode urlExpr;
	
	public Table()
		{
		
		}
	
	public String getPattern() {
		return pattern;
		}
	
	void setPattern(String pattern)
		{
		this.pattern = pattern;
		}
	
	public Column getChromColumn() {
		return chromColumn;
	}



	public Column getStartColumn() {
		return startColumn;
	}



	public Column getEndColumn() {
		return endColumn;
	}




	void setChromColumn(Column chromColumn) {
		this.chromColumn = chromColumn;
	}


	void setNameColumn(Column nameColumn) {
		this.nameColumn = nameColumn;
		}
	
	public Column getNameColumn()
		{
		return nameColumn;
		}

	void setEndColumn(Column endColumn) {
		this.endColumn = endColumn;
	}

	void setStartColumn(Column startColumn) {
		this.startColumn = startColumn;
	}

	public FirstBase getFirstBase() {
		return firstBase;
		}
	void setFirstBase(FirstBase firstBase)
		{
		this.firstBase = firstBase;
		}
	
	public ChromNameNormalizer getChromosomeNaming()
		{
		return chromosomeNaming;
		}
	
	void setChromosomeNaming(String className) throws ClassNotFoundException,IllegalAccessException,InstantiationException
		{
		if(className.equalsIgnoreCase("ensembl"))
			{
			setChromosomeNaming(new EnsemblNameNormalizer());
			}
		else if(className.equalsIgnoreCase("ucsc"))
			{
			setChromosomeNaming(new UCSCNameNormalizer());
			}
		else
			{
			setChromosomeNaming((ChromNameNormalizer)Class.forName(className).newInstance());
			}
		}
	
	void setChromosomeNaming(ChromNameNormalizer chromosomeNaming) {
		this.chromosomeNaming = chromosomeNaming;
		}
	
	public List<Column> getColumns()
		{
		return columns;
		}
	
	public int size()
		{
		return getColumns().size();
		}
	public Column get(int index)
		{
		return getColumns().get(index);
		}
	
	public Column getColumnByName(String id)
		{
		return this.id2column.get(id);
		}
	
	
	public Column getStrandColumn() {
		return strandColumn;
		}
	
	void setStrandColumn(Column strandColumn)
		{
		this.strandColumn = strandColumn;
		}
	
	void putColumn(Column c)
		{
		this.columns.add(c);
		this.id2column.put(c.getId(), c);
		}
	
	void setUrlExpr(ExprNode urlExpr) {
		this.urlExpr = urlExpr;
		}
	
	public ExprNode getUrlExpr() {
		return urlExpr;
		}
	
	
	String getXsdType()
		{
		return getId()+"Type";
		}
	
	public void writeXsd(XMLStreamWriter w) throws XMLStreamException
		{
		w.writeStartElement(XSD.prefix,"complexType",XSD.NS);
		w.writeAttribute("name", getXsdType());
		
		XSD.writeAnnotation(w, getDescription());
		
		w.writeStartElement(XSD.prefix,"complexContent",XSD.NS);
		w.writeStartElement(XSD.prefix,"extension",XSD.NS);
		w.writeAttribute("base", TNS.prefix+":"+Instance.ABSTRACT_CHROM_START_END);
		w.writeStartElement(XSD.prefix,"sequence",XSD.NS);

		for(int i=0;i< size();++i)
			{
			Column c=get(i);
			if(c.isIgnore()) continue;
			c.writeXsd(w);
			}
		
		w.writeEndElement();
		w.writeEndElement();
		w.writeEndElement();
		w.writeEndElement();
		}

	}
